home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / oscar / OscarSocket.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  14KB  |  457 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. import sys
  6. import logging
  7. import struct
  8. import socket
  9. import collections
  10. import time
  11. from threading import RLock
  12. from traceback import print_exc
  13. import hub
  14. import common
  15. import oscar
  16. from oscar.Snactivator import Snactivator
  17. from util import lock, unpack_named, Storage, to_hex, try_this, callsback, isgeneratormethod
  18. log = logging.getLogger('oscar.sock')
  19. from struct import pack, unpack
  20. from common import netcall
  21.  
  22. def flap_sequence_number():
  23.     i = 1
  24.     while None:
  25.         yield i
  26.         i += 1
  27.         if i >= 32768:
  28.             i = 1
  29.             continue
  30.         continue
  31.         return None
  32.  
  33.  
  34. class OscarSocket(common.socket):
  35.     flap_hdr_size = 6
  36.     snac_hdr_size = 10
  37.     id = 42
  38.     func_templ = '\n    def %(name)s (self):\n        print "%(name)s is not implemented!"\n        print self.hdr\n        print self.data\n    '
  39.     
  40.     def default_cb(self, *a, **kw):
  41.         log.debug_s('Socket ignoring (%s, %s)', a, kw)
  42.  
  43.     
  44.     def __repr__(self):
  45.         
  46.         try:
  47.             return '<OscarSocket %r>' % (self._OscarSocket__oserver,)
  48.         except Exception:
  49.             return '<OscarSocket ??>'
  50.  
  51.  
  52.     
  53.     def __init__(self, server, cookie = None, incoming = None, close = None, callback = None, bos = False):
  54.         common.socket.__init__(self)
  55.         if not callback:
  56.             pass
  57.         self.on_connect = self.default_cb
  58.         if not incoming:
  59.             pass
  60.         self.on_incoming = self.default_cb
  61.         if not close:
  62.             pass
  63.         self.on_close = self.default_cb
  64.         self.callbacks = collections.defaultdict(list)
  65.         self.cookie = cookie
  66.         self.rate_lock = RLock()
  67.         self.hdr = None
  68.         self.buf = ''
  69.         self.data = ''
  70.         self.seq = flap_sequence_number()
  71.         self.req = flap_sequence_number()
  72.         self.rate_classes = []
  73.         self.rates = { }
  74.         self.rate_lvl_incr = False
  75.         self.snactivate = self._send_snac
  76.         self.snactivator = None
  77.         self.bos = bos
  78.         self.set_terminator(self.flap_hdr_size)
  79.         log.info('oscar socket created, connecting to %s', server)
  80.         self._OscarSocket__oserver = server
  81.         self.connect(server, error = callback.error)
  82.  
  83.     __init__ = callsback(__init__)
  84.     
  85.     def handle_error(self, e = None):
  86.         if isinstance(e, socket.error):
  87.             if self.on_close is not None:
  88.                 log.error('Socket error for %r, calling on_close (= %r): %r', self, self.on_close, e)
  89.                 self.on_close(self)
  90.             else:
  91.                 log.info('handle_error in %r but on_close is None' % self)
  92.         
  93.         common.socket.handle_error(self, e)
  94.  
  95.     
  96.     def test_connection(self):
  97.         
  98.         try:
  99.             self.send_flap(5)
  100.         except Exception:
  101.             e = None
  102.             print_exc()
  103.             if not self.on_close:
  104.                 pass
  105.             self.default_cb(self)
  106.  
  107.  
  108.     
  109.     def apply_rates(self, rate_classes, rate_groups):
  110.         if not self.rate_classes:
  111.             self.rate_classes = rate_classes
  112.         else:
  113.             for rates in rate_classes:
  114.                 id = rates[0]
  115.                 self.rate_classes[id - 1] = rates
  116.             
  117.         self.rates.update(rate_groups)
  118.         if self.snactivator is None:
  119.             self.snactivator = Snactivator(self)
  120.             self.snactivator.start()
  121.         
  122.         self.snactivate = self.snactivator.send_snac
  123.  
  124.     apply_rates = lock(apply_rates)
  125.     
  126.     def calc_rate_level(self, rate_class):
  127.         old_level = rate_class.current_level
  128.         window = rate_class.window
  129.         now = int(time.time())
  130.         time_diff = (now - rate_class.last_time) * 1000
  131.         new_level = min(int(((window - 1) * old_level + time_diff) / window), rate_class.max_level)
  132.         return (new_level, now)
  133.  
  134.     
  135.     def snac_rate_class(self, fam, sub, *a):
  136.         
  137.         try:
  138.             return self.rate_classes[self.rates[(fam, sub)] - 1]
  139.         except KeyError:
  140.             return None
  141.  
  142.  
  143.     
  144.     def _get_rate_lvls(self, rclass):
  145.         return (rclass.max_level, rclass.current_level, rclass.alert_level, rclass.clear_level, rclass.window)
  146.  
  147.     
  148.     def time_to_send(self, s):
  149.         fam = s[0]
  150.         sub = s[1]
  151.         rclass = self.snac_rate_class(fam, sub)
  152.         (ml, curl, al, clrl, w) = self._get_rate_lvls(rclass)
  153.         threshold = min(ml, al + (clrl - al) * 2)
  154.         self.rate_lock.__enter__()
  155.         
  156.         try:
  157.             if (curl < al or self.rate_lvl_incr) and curl < threshold:
  158.                 self.rate_lvl_incr = True
  159.             else:
  160.                 self.rate_lvl_incr = False
  161.                 return 0
  162.         finally:
  163.             pass
  164.  
  165.         k = 500
  166.         step = ml / k
  167.         wait = w * step + curl
  168.         delta = rclass.last_time - int(time.time())
  169.         to_send = delta + wait / 1000
  170.         return max(0, to_send)
  171.  
  172.     
  173.     def handle_connect(self):
  174.         log.debug('connected')
  175.  
  176.     
  177.     def handle_close(self):
  178.         log.info('closed. calling on_close=%r', self.on_close)
  179.         if not self.on_close:
  180.             pass
  181.         self.default_cb(self)
  182.         self.close()
  183.  
  184.     
  185.     def handle_expt(self):
  186.         log.warning('oob data')
  187.         self.handle_close()
  188.  
  189.     
  190.     def collect_incoming_data(self, data):
  191.         pass
  192.  
  193.     
  194.     def set_terminator(self, term):
  195.         common.socket.set_terminator(self, term)
  196.  
  197.     
  198.     def found_terminator(self):
  199.         
  200.         try:
  201.             if self.hdr is None:
  202.                 self._lock.__enter__()
  203.                 
  204.                 try:
  205.                     self.hdr = unpack_named('!BBHH', 'id', 'chan', 'seq', 'size', self.buf)
  206.                     self.buf = ''
  207.                     if self.hdr.size == 0:
  208.                         self.found_terminator()
  209.                     else:
  210.                         self.set_terminator(self.hdr.size)
  211.                 finally:
  212.                     pass
  213.  
  214.             else:
  215.                 
  216.                 try:
  217.                     getattr(self, 'channel_%d' % self.hdr.chan, self.unknown_channel)()
  218.                 except oscar.errors:
  219.                     e = None
  220.                     hub.get_instance().on_error(e)
  221.                 except Exception:
  222.                     log.critical('Error handling FLAP 0x%x (DATA: %s) ' % (self.hdr.seq, repr(self.data)))
  223.                     raise 
  224.                 finally:
  225.                     self._lock.__enter__()
  226.                     
  227.                     try:
  228.                         (self.hdr, self.data) = (None, '')
  229.                         self.set_terminator(self.flap_hdr_size)
  230.                     finally:
  231.                         pass
  232.  
  233.  
  234.         except socket.error:
  235.             raise 
  236.         except Exception:
  237.             e = None
  238.             log.critical('%r had a non-socket error', self)
  239.             print_exc()
  240.         finally:
  241.             if self.terminator == 0:
  242.                 log.critical('terminator was 0, closing socket!')
  243.                 self.handle_close()
  244.             
  245.  
  246.  
  247.     
  248.     def close(self):
  249.         del self.on_incoming
  250.         self.on_incoming = None
  251.         common.socket.close(self)
  252.  
  253.     
  254.     def close_when_done(self):
  255.         self.on_close = None
  256.         if self.snactivator:
  257.             self.snactivator.stop()
  258.             del self.snactivator
  259.             self.snactivator = None
  260.         
  261.         
  262.         try:
  263.             self.send_flap(4)
  264.         except socket.error:
  265.             (errno, desc) = None
  266.             if errno not in (9, 10054, 10057):
  267.                 raise 
  268.             
  269.         except:
  270.             errno not in (9, 10054, 10057)
  271.  
  272.         common.socket.close_when_done(self)
  273.  
  274.     
  275.     def send_flap(self, chan, data = ''):
  276.         log.debug_s('Sending FLAP on channel %d, data is < %r >', chan, data)
  277.         (None, None, netcall)((lambda : common.socket.push(self, pack('!BBHH', self.id, chan, self.seq.next(), len(data)) + data)))
  278.  
  279.     
  280.     def send_snac(self, fam, sub, data = '', priority = 5, req = False, cb = None, *args, **kwargs):
  281.         req_id = self.req.next()
  282.         if req:
  283.             for k, v in list(self.callbacks.iteritems()):
  284.                 if not v:
  285.                     self.callbacks.pop(k)
  286.                     continue
  287.             
  288.             self.callbacks[req_id].append((cb, args, kwargs))
  289.         
  290.         self.snactivate((fam, sub, req_id, data), priority)
  291.  
  292.     
  293.     def _send_snac(self, .1, priority = None):
  294.         (fam, sub, req_id, data) = .1
  295.         server_version = getattr(self, 'server_snac_versions', { }).get(fam, None)
  296.         if server_version is None:
  297.             version = None
  298.         else:
  299.             my_version = getattr(getattr(oscar.snac, 'family_x%02x' % fam), 'version', None)
  300.             if my_version == server_version or my_version is None:
  301.                 version = None
  302.             else:
  303.                 version = my_version
  304.         flags = None if version is None else 32768
  305.         if version:
  306.             ver_tlv = oscar.util.tlv(1, 2, version)
  307.             ver_tlv = pack('!H', len(ver_tlv)) + ver_tlv
  308.         else:
  309.             ver_tlv = ''
  310.         log.debug('sending snac: fam=0x%02x, sub=0x%02x, req=0x%04x', fam, sub, req_id)
  311.         log.debug_s('\t\tdata=%r', data)
  312.         to_send = pack('!HHHI', fam, sub, flags, req_id) + ver_tlv + data
  313.         self.send_flap(2, to_send)
  314.         if (fam, sub) in self.rates:
  315.             rclass = self.snac_rate_class(fam, sub)
  316.             (rclass.current_level, rclass.last_time) = self.calc_rate_level(rclass)
  317.             clevel = rclass.current_level
  318.             i = sorted(list(self._get_rate_lvls(rclass)) + [
  319.                 clevel]).index(clevel)
  320.             (hi, lo) = ('disconnect', 'limit', 'alert', 'clear', 'max')[i:i + 2]
  321.             if not hi == 'clear' and lo == 'max':
  322.                 log.debug('current rate level is: %s < %d < %s', hi, clevel, lo)
  323.             
  324.         
  325.  
  326.     
  327.     def channel_1(self):
  328.         log.info('got channel 1 (new connection) flap')
  329.         to_send = pack('!I', 1)
  330.         if self.cookie is not None:
  331.             to_send += oscar.util.tlv(6, self.cookie)
  332.             self._lock.__enter__()
  333.             
  334.             try:
  335.                 self.cookie = None
  336.             finally:
  337.                 pass
  338.  
  339.         
  340.         self.send_flap(1, to_send)
  341.         
  342.         try:
  343.             if not self.on_connect:
  344.                 pass
  345.             self.default_cb(self)
  346.         except StopIteration:
  347.             pass
  348.  
  349.         del self.on_connect
  350.         self.on_connect = None
  351.  
  352.     
  353.     def channel_2(self):
  354.         hdr = unpack_named('!HHHI', 'fam', 'sub', 'flags', 'req', self.data[:self.snac_hdr_size])
  355.         data = self.data[self.snac_hdr_size:]
  356.         log.debug('got channel 2 (snac data) flap. fam=0x%02x, sub=0x%02x, req=0x%04x', hdr.fam, hdr.sub, hdr.req)
  357.         log.debug_s('\t\tdata=%r', data)
  358.         snac = Storage(hdr = hdr, data = data)
  359.         if snac.hdr.flags & 32768:
  360.             log.debug('got version data for snac, trimming')
  361.             snac_ver_fmt = (('tlvs_len', 'H'), ('tlvs', 'tlv_list_len', 'tlvs_len'))
  362.             (tlvs_len, ver, snac.data) = oscar.util.apply_format(snac_ver_fmt, snac.data)
  363.         
  364.         if self.is_ignored(snac):
  365.             log.debug('Ignored snac: %r', snac)
  366.             return None
  367.         
  368.         cbs = self.callbacks
  369.         
  370.         try:
  371.             if snac.hdr.req in cbs:
  372.                 call_later = []
  373.                 for func, args, kwargs in cbs[snac.hdr.req]:
  374.                     if snac.hdr.flags & 1:
  375.                         call_later.append((func, args, kwargs))
  376.                     
  377.                     if isgeneratormethod(func):
  378.                         
  379.                         try:
  380.                             func((self, snac) + args)
  381.                         except StopIteration:
  382.                             pass
  383.                         except:
  384.                             None<EXCEPTION MATCH>StopIteration
  385.                         
  386.  
  387.                     None<EXCEPTION MATCH>StopIteration
  388.                     func(self, snac, *args, **kwargs)
  389.                 
  390.                 self._lock.__enter__()
  391.                 
  392.                 try:
  393.                     if not call_later:
  394.                         cbs.pop(snac.hdr.req)
  395.                     else:
  396.                         cbs[snac.hdr.req] = call_later
  397.                 finally:
  398.                     pass
  399.  
  400.             elif self.on_incoming is None:
  401.                 self.default_cb(self, snac)
  402.             elif isgeneratormethod(self.on_incoming):
  403.                 
  404.                 try:
  405.                     self.on_incoming((self, snac))
  406.                 except StopIteration:
  407.                     pass
  408.                 except Exception:
  409.                     print repr(snac)
  410.                     raise 
  411.                 except:
  412.                     None<EXCEPTION MATCH>StopIteration
  413.                 
  414.  
  415.             None<EXCEPTION MATCH>StopIteration
  416.             self.on_incoming(self, snac)
  417.         except oscar.snac.SnacError:
  418.             e = None
  419.             (fam, _) = ()
  420.             (sub, _) = e.args[:2]
  421.             if (fam, sub) in self.ignored_errors:
  422.                 log.error('SNAC error occured: %r', snac)
  423.             else:
  424.                 hub.get_instance().on_error(e)
  425.         except:
  426.             (fam, sub) in self.ignored_errors
  427.  
  428.  
  429.     
  430.     def is_ignored(self, snac):
  431.         if (snac.hdr.fam, snac.hdr.sub) in self.ignored_snacs:
  432.             return True
  433.         
  434.  
  435.     ignored_snacs = [
  436.         (1, 19)]
  437.     ignored_errors = [
  438.         (1, 13),
  439.         (21, 2),
  440.         (19, 1),
  441.         (21, 5)]
  442.     
  443.     def channel_4(self):
  444.         log.info('got channel 4 (close connection) flap')
  445.         fmt = (('tlvs', 'tlv_dict'),)
  446.         (tlvs, data) = oscar.unpack(fmt, self.data)
  447.         None if (try_this,)((lambda : ord(tlvs[9][-1])), False) else self.default_cb(self)
  448.         del self.on_close
  449.         self.on_close = None
  450.         self.close_when_done()
  451.  
  452.     
  453.     def unknown_channel(self):
  454.         log.warning('Unknown channel for data: %r', self.data)
  455.  
  456.  
  457.